<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>Electron学习入门笔记 | LenlBlog</title><meta name="author" content="Lenl,lenl412@163.com"><meta name="copyright" content="Lenl"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="ffffff"><meta name="description" content="想学习一下客户端开发框架Electron">
<meta property="og:type" content="article">
<meta property="og:title" content="Electron学习入门笔记">
<meta property="og:url" content="https://lienle.gitee.io/notes/electronLearn/index.html">
<meta property="og:site_name" content="LenlBlog">
<meta property="og:description" content="想学习一下客户端开发框架Electron">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png">
<meta property="article:published_time" content="2023-05-06T13:17:09.000Z">
<meta property="article:modified_time" content="2023-05-16T07:32:23.053Z">
<meta property="article:author" content="Lenl">
<meta property="article:tag" content="Vue">
<meta property="article:tag" content="Electron">
<meta property="article:tag" content="Node.Js">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png"><link rel="shortcut icon" href="/img/lenl.png"><link rel="canonical" href="https://lienle.gitee.io/notes/electronLearn/index.html"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//hm.baidu.com"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><meta name="baidu-site-verification" content="codeva-6HME93uF43"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.min.css" media="print" onload="this.media='all'"><script>var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?629608ec0c773bd9f96cb72389693ab9";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/search.xml","preload":false,"top_n_per_article":1,"unescape":false,"languages":{"hits_empty":"找不到您查询的内容：${query}","hits_stats":"共找到 ${hits} 篇文章"}},
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  dateSuffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: {"limitCount":50,"languages":{"author":"作者: Lenl","link":"链接: ","source":"来源: LenlBlog","info":"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: true,
  islazyload: true,
  isAnchor: false,
  percent: {
    toc: true,
    rightside: false,
  }
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'Electron学习入门笔记',
  isPost: true,
  isHome: false,
  isHighlightShrink: true,
  isToc: true,
  postUpdate: '2023-05-16 15:32:23'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
    win.getCSS = (url,id = false) => new Promise((resolve, reject) => {
      const link = document.createElement('link')
      link.rel = 'stylesheet'
      link.href = url
      if (id) link.id = id
      link.onerror = reject
      link.onload = link.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        link.onload = link.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(link)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', 'ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script></head><body><!--include ./fullpage-loading.pug--><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="wizard-scene"><div class="wizard-objects"><div class="wizard-square"></div><div class="wizard-circle"></div><div class="wizard-triangle"></div></div><div class="wizard"><div class="wizard-body"></div><div class="wizard-right-arm"><div class="wizard-right-hand"></div></div><div class="wizard-left-arm"><div class="wizard-left-hand"></div></div><div class="wizard-head"><div class="wizard-beard"></div><div class="wizard-face"><div class="wizard-adds"></div></div><div class="wizard-hat"><div class="wizard-hat-of-the-hat"></div><div class="wizard-four-point-star --first"></div><div class="wizard-four-point-star --second"></div><div class="wizard-four-point-star --third"></div></div></div></div></div></div><script>const preloader = {
  endLoading: () => {
    document.body.style.overflow = '';
    document.getElementById('loading-box').classList.add("loaded")
  },
  initLoading: () => {
    document.body.style.overflow = 'hidden';
    document.getElementById('loading-box').classList.remove("loaded")
  }
}

preloader.initLoading()
window.addEventListener('load',()=> { preloader.endLoading() })
//避免加载时间过长
setTimeout(function(){preloader.endLoading();}, 3000);

if (false) {
  document.addEventListener('pjax:send', () => { preloader.initLoading() })
  document.addEventListener('pjax:complete', () => { preloader.endLoading() })
}</script><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "/img/hexo_loading.gif" data-lazy-src="/img/lenl.png" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">17</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">25</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">8</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 存档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 分享</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/collect/"><i class="fa-fw fas fa-book"></i><span> 大佬们の干货</span></a></li><li><a class="site-page child" href="/resources/"><i class="fa-fw fab fa-dropbox"></i><span> 屯屯鼠の资源</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg fixed" id="page-header" style="background-image: url('https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png')"><nav id="nav"><span id="blog-info"><a href="/" title="LenlBlog"><img class="site-icon" src= "/img/hexo_loading.gif" data-lazy-src="/img/lenl.png"/><span class="site-name">LenlBlog</span></a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search" href="javascript:void(0);"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 存档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 分享</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/collect/"><i class="fa-fw fas fa-book"></i><span> 大佬们の干货</span></a></li><li><a class="site-page child" href="/resources/"><i class="fa-fw fab fa-dropbox"></i><span> 屯屯鼠の资源</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page" href="javascript:void(0);"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">Electron学习入门笔记</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2023-05-06T13:17:09.000Z" title="发表于 2023-05-06 21:17:09">2023-05-06</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2023-05-16T07:32:23.053Z" title="更新于 2023-05-16 15:32:23">2023-05-16</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/">学习笔记</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">5.4k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>24分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="Electron学习入门笔记"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span><span class="post-meta-separator">|</span><span class="post-meta-commentcount"><i class="far fa-comments fa-fw post-meta-icon"></i><span class="post-meta-label">评论数:</span><a href="/notes/electronLearn/#post-comment" itemprop="discussionUrl"><span class="valine-comment-count" data-xid="/notes/electronLearn/" itemprop="commentCount"><i class="fa-solid fa-spinner fa-spin"></i></span></a></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><div class="note warning simple"><p>置顶：</p>
<p>本文档为根据学习教程 <a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1xd4y1J7dB">Electron入门</a> 的前几P的基本api记录。教程中基于Electron与React做了一个markdown编辑器的小项目。本人根据自己掌握的知识，用Electron与Vue进行了复现。以下链接可供交流学习参考：</p>
<p><a target="_blank" rel="noopener" href="https://gitee.com/lienle/electron_markdown_editor_demo">electron_vue_markdown_editor源码仓库</a></p>
<p><a target="_blank" rel="noopener" href="https://gitee.com/lienle/electron_markdown_editor_demo/releases/tag/v1">electron_vue_markdown_editor 初版安装包下载 </a></p>
</div> 
<h2 id="Electron基本">Electron基本</h2>
<p>Electron由Chromium、Node.js、Native apis 三部分组成。</p>
<h3 id="技术架构">技术架构</h3>
<ul class="lvl-0">
<li class="lvl-2">
<p>Chromium：支持最新特性的浏览器</p>
</li>
<li class="lvl-2">
<p>Node.js：javascript运行时，可实现文件读写等</p>
</li>
<li class="lvl-2">
<p>Native APIs：提供统一的原生界面能力</p>
</li>
</ul>
<h3 id="Electron工作流程">Electron工作流程</h3>
<p><a target="_blank" rel="noopener" href="https://z4a.net/image/VwTT8n"><img src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/05/06/Electron.md.png" alt="Electron工作流程示意图"></a></p>
<h4 id="主进程">主进程</h4>
<ul class="lvl-0">
<li class="lvl-2">
<p>可以看作package.json中main属性对应的文件</p>
</li>
<li class="lvl-2">
<p>一个应用只会有一个主进程</p>
</li>
<li class="lvl-2">
<p>只有主进程可以进行GUI的api操作</p>
</li>
<li class="lvl-2">
<p>主进程可以调用操作系统底层api对本地文件进行操作</p>
</li>
</ul>
<h4 id="渲染进程">渲染进程</h4>
<ul class="lvl-0">
<li class="lvl-2">
<p>Windows中展示的界面通过渲染进程表现</p>
</li>
<li class="lvl-2">
<p>一个应用可以有多个渲染进程</p>
</li>
<li class="lvl-2">
<p>渲染进程如果需要调用原生api需要用ipc与主进程进行通信</p>
</li>
</ul>
<h3 id="Electron环境搭建">Electron环境搭建</h3>
<p>可以参考：<a target="_blank" rel="noopener" href="https://www.electronjs.org/zh">electron官网</a></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># clone示例项目代码</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/electron/electron-quick-start</span><br><span class="line"><span class="comment"># 进入，安装依赖并启动</span></span><br><span class="line">npm install &amp;&amp; npm start</span><br></pre></td></tr></table></figure>
<p>这里install失败的话可以安装cnpm，用淘宝镜像install，但是cnpm貌似不受 <code>package-lock.json</code> 影响。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install -g cnpm --registry=https://registry.npm.taobao.org</span><br></pre></td></tr></table></figure>
<p>入口文件main.js中：</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="comment">//1.创建了窗口</span></span><br><span class="line"><span class="comment">//2.加载了界面index.html，使用web技术实现的，这个界面时运行在渲染进程中的</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">createWindow</span> () &#123;</span><br><span class="line">  <span class="comment">// Create the browser window.</span></span><br><span class="line">  <span class="keyword">const</span> mainWindow = <span class="keyword">new</span> <span class="title class_">BrowserWindow</span>(&#123;</span><br><span class="line">    <span class="attr">width</span>: <span class="number">800</span>,</span><br><span class="line">    <span class="attr">height</span>: <span class="number">600</span>,</span><br><span class="line">    <span class="attr">webPreferences</span>: &#123;</span><br><span class="line">      <span class="attr">preload</span>: path.<span class="title function_">join</span>(__dirname, <span class="string">&#x27;preload.js&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)</span><br><span class="line">  <span class="comment">// and load the index.html of the app.</span></span><br><span class="line">  mainWindow.<span class="title function_">loadFile</span>(<span class="string">&#x27;index.html&#x27;</span>)</span><br><span class="line">  <span class="comment">// Open the DevTools.</span></span><br><span class="line">  <span class="comment">// mainWindow.webContents.openDevTools()</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>我们自己可以根据官方文档创建一个空的干净的electron项目</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> my-electron-app &amp;&amp; <span class="built_in">cd</span> my-electron-app</span><br><span class="line">npm init</span><br></pre></td></tr></table></figure>
<p>填写相关信息后，package.json应该像这样：</p>
<figure class="highlight json"><table><tr><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;my-electron-app&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;description&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Hello World!&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;main&quot;</span><span class="punctuation">:</span> <span class="string">&quot;main.js&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;author&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Jane Doe&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;license&quot;</span><span class="punctuation">:</span> <span class="string">&quot;MIT&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>
<p>然后安装electron</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install --save-dev electron</span><br></pre></td></tr></table></figure>
<p>在package.json的scripts加入命令：</p>
<figure class="highlight json"><table><tr><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;start&quot;</span><span class="punctuation">:</span> <span class="string">&quot;electron .&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>
<p>执行 <code>npm start</code> 即可。</p>
<p>基本入门可以跟着官方文档敲。</p>
<h2 id="Electron学习">Electron学习</h2>
<h3 id="Electron生命周期事件">Electron生命周期事件</h3>
<ul class="lvl-0">
<li class="lvl-2">
<p>ready :app初始化完成</p>
</li>
<li class="lvl-2">
<p>dom-ready:一个窗口中的文本加载完成</p>
</li>
<li class="lvl-2">
<p>did-fibish-load:窗口导航完成时触发</p>
</li>
<li class="lvl-2">
<p>window-all-closed:所有窗口都被关闭时触发(如果监听了该事件且没有在这里面执行quit，则后面三个事件将会失效)</p>
</li>
<li class="lvl-2">
<p>before-quit:在关闭窗口之前触发</p>
</li>
<li class="lvl-2">
<p>will-quit:在窗口关闭并且应用退出时触发</p>
</li>
<li class="lvl-2">
<p>quit:当所有窗口被关闭时触发</p>
</li>
<li class="lvl-2">
<p>closed:当窗口关闭时触发，此时应删除窗口引用</p>
</li>
</ul>
<p>使用举例：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//所有窗口都关闭</span></span><br><span class="line">app.<span class="title function_">on</span>(<span class="string">&#x27;window-all-closed&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;444 ---&gt; all windows are closed&#x27;</span>)</span><br><span class="line">    <span class="comment">//只有quit了后面的三个事件才会生效</span></span><br><span class="line">    app.<span class="title function_">quit</span>()</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">//app退出前</span></span><br><span class="line">app.<span class="title function_">on</span>(<span class="string">&#x27;before-quit&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;555 ---&gt; before-quit&#x27;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">//app退出时</span></span><br><span class="line">app.<span class="title function_">on</span>(<span class="string">&#x27;will-quit&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;666 ---&gt; will-quit&#x27;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">//app退出</span></span><br><span class="line">app.<span class="title function_">on</span>(<span class="string">&#x27;quit&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;777 ---&gt; quit&#x27;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>窗口的：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> mainWin=<span class="keyword">new</span> <span class="title class_">BrowserWindow</span>(&#123;</span><br><span class="line">    <span class="attr">width</span>:<span class="number">600</span>,</span><br><span class="line">    <span class="attr">height</span>:<span class="number">400</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">//在当前窗口中加载指定界面让它显示具体的内容</span></span><br><span class="line">mainWin.<span class="title function_">loadFile</span>(<span class="string">&#x27;index.html&#x27;</span>)</span><br><span class="line"></span><br><span class="line">mainWin.<span class="title function_">on</span>(<span class="string">&#x27;close&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;8888 this window closed~~~~~~&#x27;</span>)</span><br><span class="line">    <span class="comment">//释放资源</span></span><br><span class="line">    <span class="comment">//mainWin=null</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">//dom加载完成事件</span></span><br><span class="line">mainWin.<span class="property">webContents</span>.<span class="title function_">on</span>(<span class="string">&#x27;dom-ready&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;222----&gt;dom-ready&#x27;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">//导航完成事件</span></span><br><span class="line">mainWin.<span class="property">webContents</span>.<span class="title function_">on</span>(<span class="string">&#x27;did-finish-load&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;3333----&gt;did-finish-load&#x27;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h3 id="关于窗口">关于窗口</h3>
<p>为了方便即时调试，可以修改一下package.json:</p>
<figure class="highlight json"><table><tr><td class="code"><pre><span class="line"><span class="comment">//监听main.js的变化</span></span><br><span class="line"><span class="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;start&quot;</span><span class="punctuation">:</span><span class="string">&quot;nodemon --watch main.js --exec npm run build&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;build&quot;</span><span class="punctuation">:</span><span class="string">&quot;electron .&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br></pre></td></tr></table></figure>
<h4 id="窗口尺寸">窗口尺寸</h4>
<p>再定义窗口时配置各项窗口尺寸配置项，详情可见官方文档</p>
<h4 id="窗口标题及环境">窗口标题及环境</h4>
<p>仍然可以在配置项里设置title，但是需要将html的title去掉。</p>
<p>图标为配置项 icon</p>
<p>菜单项为frame,用于自定义菜单，设为false会隐藏，但是就不能拖动了</p>
<p>置隐藏菜单为autoHideMenuBar,</p>
<p>透明度为transparent</p>
<p>ctrl+shift+i 可以调出调试面板</p>
<p>在渲染进程中如何创建新窗口呢？</p>
<p>首先需要在main.js的创建的主窗口配置项中设置：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> mainWin=<span class="keyword">new</span> <span class="title class_">BrowserWindow</span>(&#123;</span><br><span class="line">    <span class="comment">//在该窗口下也能使用node进程</span></span><br><span class="line">    <span class="attr">webPreferences</span>:&#123;</span><br><span class="line">        <span class="attr">nodeIntegration</span>:<span class="literal">true</span>,</span><br><span class="line">        <span class="attr">contextIsolation</span>:<span class="literal">false</span>,</span><br><span class="line">        <span class="attr">enableRemoteModule</span>:<span class="literal">true</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>然后在渲染进程的js中引入remote</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123;remote&#125;=<span class="built_in">require</span>(<span class="string">&#x27;electron&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">//点击按钮打开新窗口</span></span><br><span class="line"><span class="keyword">const</span> oBtn=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;btn&#x27;</span>)</span><br><span class="line">oBtn.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="comment">//在渲染进程中如何创建窗口</span></span><br><span class="line">    <span class="keyword">let</span> indexWin=<span class="keyword">new</span> remote.<span class="title class_">BrowserWindow</span>(&#123;</span><br><span class="line">        <span class="attr">width</span>:<span class="number">200</span>,</span><br><span class="line">        <span class="attr">height</span>:<span class="number">200</span></span><br><span class="line">    &#125;)</span><br><span class="line">    indexWin.<span class="title function_">loadFile</span>(<span class="string">&#x27;list.html&#x27;</span>)</span><br><span class="line">    indexWin.<span class="title function_">on</span>(<span class="string">&#x27;close&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        indexWin = <span class="literal">null</span></span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>但是这一方式在最新版(v24)已经不适用了。</p>
<p>此时需要引入新的模块：</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install --save @electron/remote</span><br></pre></td></tr></table></figure>
<p>然后在主进程中引入</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> rm= <span class="built_in">require</span>(<span class="string">&#x27;@electron/remote/main&#x27;</span>)</span><br></pre></td></tr></table></figure>
<p>在主窗口的配置中 <code>enableRemoteModule</code> 可以舍去，定义完成主窗口，loadFile前：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">rm.<span class="title function_">initialize</span>()</span><br><span class="line">rm.<span class="title function_">enable</span>(mainWin.<span class="property">webContents</span>)</span><br></pre></td></tr></table></figure>
<p>然后在渲染进程的js中即可：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123;<span class="title class_">BrowserWindow</span>&#125;=<span class="built_in">require</span>(<span class="string">&#x27;@electron/remote&#x27;</span>)</span><br></pre></td></tr></table></figure>
<p>直接使用BrowserWindow即可。</p>
<h4 id="自定义窗口">自定义窗口</h4>
<p>在main.js中设置 <code>frame:false</code> 此时可以自定义窗口，然后进行一些自定义按钮操作：</p>
<p>如，index.html中：</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">link</span> <span class="attr">href</span>=<span class="string">&quot;https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css&quot;</span> <span class="attr">rel</span>=<span class="string">&quot;stylesheet&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;index.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;box&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;bar&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;titleBar&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;logo&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;title&quot;</span>&gt;</span>自定义窗口<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;windowTool&quot;</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;close&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fa fa-window-close-o&quot;</span> <span class="attr">aria-hidden</span>=<span class="string">&quot;true&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;maxsize&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fa fa-window-maximize&quot;</span> <span class="attr">aria-hidden</span>=<span class="string">&quot;true&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;minisize&quot;</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">i</span> <span class="attr">class</span>=<span class="string">&quot;fa fa-minus&quot;</span> &gt;</span><span class="tag">&lt;/<span class="name">i</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            </span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">hr</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">            我是自定义窗口</span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>自定义了如下css:</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line">&lt;style&gt;</span><br><span class="line">    *&#123;</span><br><span class="line">        <span class="attribute">margin</span>: <span class="number">0</span>;</span><br><span class="line">        <span class="attribute">padding</span>: <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="selector-class">.box</span>&#123;</span><br><span class="line">        <span class="attribute">width</span>: <span class="number">100%</span>;</span><br><span class="line">        <span class="attribute">height</span>: <span class="number">400px</span>;</span><br><span class="line">        <span class="attribute">overflow</span>: hidden;</span><br><span class="line">        <span class="attribute">background-color</span>: seashell;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="selector-class">.bar</span>&#123;</span><br><span class="line">        <span class="attribute">height</span>: <span class="number">40px</span>;</span><br><span class="line">        <span class="attribute">box-shadow</span>: <span class="number">0</span> <span class="number">1</span> <span class="number">5px</span> <span class="number">0px</span> <span class="number">#333</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="selector-class">.titleBar</span>&#123;</span><br><span class="line">        <span class="attribute">width</span>: <span class="number">190px</span>;</span><br><span class="line">        <span class="attribute">float</span>: left;</span><br><span class="line">        <span class="attribute">height</span>: <span class="number">40px</span>;</span><br><span class="line">        <span class="attribute">margin-left</span>: <span class="number">10px</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="selector-class">.titleBar</span> <span class="selector-tag">div</span>&#123;</span><br><span class="line">        <span class="attribute">float</span><span class="selector-pseudo">:left</span>;</span><br><span class="line">        <span class="attribute">height</span>: <span class="number">40px</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="selector-class">.titleBar</span> <span class="selector-class">.logo</span>&#123;</span><br><span class="line">        <span class="attribute">width</span>: <span class="number">20px</span>;</span><br><span class="line">        <span class="attribute">height</span>: <span class="number">20px</span>;</span><br><span class="line">        <span class="attribute">margin-top</span>: <span class="number">10px</span>;</span><br><span class="line">        <span class="attribute">background</span>: <span class="built_in">url</span>(<span class="string">./logo.ico</span>);</span><br><span class="line">        <span class="attribute">background-size</span>: cover;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="selector-class">.titleBar</span> <span class="selector-class">.title</span>&#123;</span><br><span class="line">        <span class="attribute">margin-left</span>: <span class="number">10px</span>;</span><br><span class="line">        <span class="attribute">font</span>: normal <span class="number">14px</span>/<span class="number">40px</span> <span class="string">&#x27;微软雅黑&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="selector-class">.windowTool</span>&#123;</span><br><span class="line">        <span class="attribute">float</span>: right;</span><br><span class="line">        <span class="attribute">width</span>: <span class="number">600px</span>;</span><br><span class="line">        <span class="attribute">height</span>: <span class="number">40px</span>;</span><br><span class="line">        <span class="attribute">position</span>: relative;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="selector-class">.windowTool</span> <span class="selector-tag">div</span>&#123;</span><br><span class="line">        <span class="attribute">float</span>: right;</span><br><span class="line">        <span class="attribute">cursor</span>: pointer;</span><br><span class="line">        <span class="attribute">margin-right</span>: <span class="number">20px</span>;</span><br><span class="line">        <span class="attribute">font</span>: normal <span class="number">12px</span>/<span class="number">40px</span> <span class="string">&#x27;微软雅黑&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&lt;/style&gt;</span><br></pre></td></tr></table></figure>
<p>自定义index.js</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123;<span class="title class_">BrowserWindow</span>,getCurrentWindow&#125;=<span class="built_in">require</span>(<span class="string">&#x27;@electron/remote&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="variable language_">window</span>.<span class="title function_">addEventListener</span>(<span class="string">&#x27;DOMContentLoaded&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="comment">//获取当前窗口对象</span></span><br><span class="line">    <span class="keyword">let</span> mainWin=<span class="title function_">getCurrentWindow</span>()</span><br><span class="line"></span><br><span class="line">    <span class="comment">//获取元素提添加点击操作的监听</span></span><br><span class="line">    <span class="keyword">let</span> aBtn=<span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(<span class="string">&#x27;windowTool&#x27;</span>)[<span class="number">0</span>].<span class="title function_">getElementsByTagName</span>(<span class="string">&#x27;div&#x27;</span>)</span><br><span class="line">    <span class="comment">//关闭按钮</span></span><br><span class="line">    aBtn[<span class="number">0</span>].<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        <span class="comment">//关闭窗口</span></span><br><span class="line">        mainWin.<span class="title function_">close</span>()</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="comment">//最大化</span></span><br><span class="line">    aBtn[<span class="number">1</span>].<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        <span class="keyword">var</span> isMax=mainWin.<span class="title function_">isMaximized</span>()</span><br><span class="line">        <span class="keyword">if</span>(!isMax)&#123;</span><br><span class="line">            <span class="comment">//窗口最大化</span></span><br><span class="line">            mainWin.<span class="title function_">maximize</span>()</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="comment">//回到初始状态</span></span><br><span class="line">            mainWin.<span class="title function_">restore</span>()</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="comment">//最小化</span></span><br><span class="line">    aBtn[<span class="number">2</span>].<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        <span class="keyword">var</span> isMin=mainWin.<span class="title function_">isMinimized</span>()</span><br><span class="line">        <span class="keyword">if</span>(!isMin)&#123;</span><br><span class="line">            <span class="comment">//窗口最小化</span></span><br><span class="line">            mainWin.<span class="title function_">minimize</span>()</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="comment">//回到初始状态</span></span><br><span class="line">            mainWin.<span class="title function_">restore</span>()</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line"></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>即可实现自定义窗口的展示、最大最小化以及关闭。</p>
<h4 id="阻止窗口关闭">阻止窗口关闭</h4>
<p>窗口关闭时应该有提示确认信息</p>
<p>在index.html中加入一个悬浮框提示</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--定义浮窗设置阻止窗口关闭样式--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;isClose&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h3</span>&gt;</span>是否关闭当前应用？<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span>&gt;</span>系统可能不会保存您的所有更改<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;close_btn&quot;</span>&gt;</span><span class="tag">&lt;<span class="name">span</span>&gt;</span>是<span class="tag">&lt;/<span class="name">span</span>&gt;</span><span class="tag">&lt;<span class="name">span</span>&gt;</span>否<span class="tag">&lt;/<span class="name">span</span>&gt;</span><span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">style</span>&gt;</span><span class="language-css"></span></span><br><span class="line"><span class="language-css"><span class="selector-class">.isClose</span>&#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">background-color</span>: cadetblue;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">display</span>: none;</span></span><br><span class="line"><span class="language-css">&#125;</span></span><br><span class="line"><span class="language-css"></span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>在index.js中阻止窗口关闭事件并接替：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//获取当前窗口对象</span></span><br><span class="line"><span class="keyword">let</span> mainWin=<span class="title function_">getCurrentWindow</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment">//监听窗口关闭操作</span></span><br><span class="line"><span class="variable language_">window</span>.<span class="property">onbeforeunload</span>=<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">let</span> oBox=<span class="variable language_">document</span>.<span class="title function_">getElementsByClassName</span>(<span class="string">&#x27;isClose&#x27;</span>)[<span class="number">0</span>]</span><br><span class="line">    oBox.<span class="property">style</span>.<span class="property">display</span>=<span class="string">&#x27;block&#x27;</span></span><br><span class="line">	</span><br><span class="line">    <span class="comment">//确定按钮</span></span><br><span class="line">    <span class="keyword">let</span> yeBtn=oBox.<span class="title function_">getElementsByTagName</span>(<span class="string">&#x27;span&#x27;</span>)[<span class="number">0</span>]</span><br><span class="line">    <span class="comment">//取消按钮</span></span><br><span class="line">    <span class="keyword">let</span> noBtn=oBox.<span class="title function_">getElementsByTagName</span>(<span class="string">&#x27;span&#x27;</span>)[<span class="number">1</span>]</span><br><span class="line">    yeBtn.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        mainWin.<span class="title function_">destroy</span>() <span class="comment">//要调用destory，而不能close，否则死循环。</span></span><br><span class="line">    &#125;)</span><br><span class="line">    noBtn.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        oBox.<span class="property">style</span>.<span class="property">display</span>=<span class="string">&#x27;none&#x27;</span></span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="父子及模态窗口">父子及模态窗口</h4>
<p>一般情况下添加新的窗口，其与初始窗口并没有什么关系。此时再新增窗口的配置项中添加如下：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">let</span> indexWin=<span class="keyword">new</span> <span class="title class_">BrowserWindow</span>(&#123;</span><br><span class="line">    <span class="attr">parent</span>:mainWin, <span class="comment">//使主窗口为父窗口</span></span><br><span class="line">    <span class="attr">modal</span>:<span class="literal">true</span>, <span class="comment">//设置为模态窗口</span></span><br><span class="line">    <span class="attr">width</span>:<span class="number">200</span>,</span><br><span class="line">    <span class="attr">height</span>:<span class="number">200</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>这样之后新开的窗口会成为模态窗口，打开时，原窗口将无法被操作，只有模态窗口关闭后才能操作原窗口。</p>
<h4 id="关于文档">关于文档</h4>
<p>用的比较多的会是官网的api参考：<a target="_blank" rel="noopener" href="https://www.electronjs.org/zh/docs/latest/api/app">Electron API 参考</a></p>
<p>这里分了5个大类，需要时可在对应模块查找。</p>
<h3 id="关于菜单">关于菜单</h3>
<h4 id="自定义菜单">自定义菜单</h4>
<blockquote>
<p>文档在 Main Process模块的Menu以及MenuItem</p>
</blockquote>
<p>首先需要根据官网要求的格式定义一个菜单项配置：</p>
<p>这里我写在一个单独文件中，然后在需要用的地方引入，注意使用exports的语法。</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">let</span> mainMenu=[</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="attr">label</span>:<span class="string">&#x27;文件&#x27;</span>,</span><br><span class="line">        <span class="attr">submenu</span>:[</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="attr">label</span>:<span class="string">&#x27;打开文件&#x27;</span>,</span><br><span class="line">                <span class="title function_">click</span>(<span class="params"></span>)&#123;</span><br><span class="line">                    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;点击菜单项要做的动作-打开文件&#x27;</span>)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="attr">type</span>:<span class="string">&#x27;separator&#x27;</span> <span class="comment">//分割线</span></span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;<span class="attr">label</span>:<span class="string">&#x27;关闭文件夹&#x27;</span>&#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="attr">label</span>:<span class="string">&#x27;关于&#x27;</span>,</span><br><span class="line">                <span class="attr">role</span>:<span class="string">&#x27;about&#x27;</span>,<span class="comment">//预设的功能，详见文档</span></span><br><span class="line">            &#125;,</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;<span class="attr">label</span>:<span class="string">&#x27;编辑&#x27;</span>&#125;,</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="built_in">exports</span>.<span class="property">mainMenu</span>=mainMenu</span><br></pre></td></tr></table></figure>
<p>引入的时候也需要使用require</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123; mainMenu &#125; = <span class="built_in">require</span>(<span class="string">&#x27;./menu/menu&#x27;</span>)</span><br></pre></td></tr></table></figure>
<p>然后在主窗口loadFile之前添加如下：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//定义或引入自己需要的菜单项js</span></span><br><span class="line"><span class="comment">//利用模板生成菜单项</span></span><br><span class="line"><span class="keyword">let</span> menu=<span class="title class_">Menu</span>.<span class="title function_">buildFromTemplate</span>(mainMenu)</span><br><span class="line"></span><br><span class="line"><span class="comment">//将上述自定义菜单添加到应用里</span></span><br><span class="line"><span class="title class_">Menu</span>.<span class="title function_">setApplicationMenu</span>(menu)</span><br><span class="line"><span class="comment">//打印当前操作系统，一些菜单项支持不同的操作系统，可以进行判断</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(process.<span class="property">platform</span>)</span><br></pre></td></tr></table></figure>
<p>这样即可初步实现自定义菜单及其功能。更多详细功能参见官方文档。</p>
<h4 id="菜单角色及类型">菜单角色及类型</h4>
<p>electron预设了一些菜单角色和类型，代码和注释如下：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">let</span> mainMenu=[</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="attr">label</span>:<span class="string">&#x27;角色&#x27;</span>, <span class="comment">//基本角色使用</span></span><br><span class="line">        <span class="attr">submenu</span>:[</span><br><span class="line">            &#123;<span class="attr">label</span>:<span class="string">&#x27;复制&#x27;</span>,<span class="attr">role</span>:<span class="string">&#x27;copy&#x27;</span>&#125;,</span><br><span class="line">            &#123;<span class="attr">label</span>:<span class="string">&#x27;剪切&#x27;</span>,<span class="attr">role</span>:<span class="string">&#x27;cut&#x27;</span>&#125;,</span><br><span class="line">            &#123;<span class="attr">label</span>:<span class="string">&#x27;粘贴&#x27;</span>,<span class="attr">role</span>:<span class="string">&#x27;paste&#x27;</span>&#125;,</span><br><span class="line">            &#123;<span class="attr">label</span>:<span class="string">&#x27;最小化&#x27;</span>,<span class="attr">role</span>:<span class="string">&#x27;minimize&#x27;</span>&#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="attr">label</span>:<span class="string">&#x27;类型&#x27;</span>, <span class="comment">//菜单四种类型</span></span><br><span class="line">        <span class="attr">submenu</span>:[</span><br><span class="line">            &#123;<span class="attr">label</span>:<span class="string">&#x27;选项1&#x27;</span>,<span class="attr">type</span>:<span class="string">&#x27;checkbox&#x27;</span>&#125;,</span><br><span class="line">            &#123;<span class="attr">label</span>:<span class="string">&#x27;选项2&#x27;</span>,<span class="attr">type</span>:<span class="string">&#x27;checkbox&#x27;</span>&#125;,</span><br><span class="line">            &#123;<span class="attr">label</span>:<span class="string">&#x27;选项3&#x27;</span>,<span class="attr">type</span>:<span class="string">&#x27;checkbox&#x27;</span>&#125;,</span><br><span class="line">            &#123;<span class="attr">type</span>:<span class="string">&#x27;separator&#x27;</span>&#125;,</span><br><span class="line">            &#123;<span class="attr">label</span>:<span class="string">&#x27;item1&#x27;</span>,<span class="attr">type</span>:<span class="string">&#x27;radio&#x27;</span>&#125;,</span><br><span class="line">            &#123;<span class="attr">label</span>:<span class="string">&#x27;item2&#x27;</span>,<span class="attr">type</span>:<span class="string">&#x27;radio&#x27;</span>&#125;,</span><br><span class="line">            &#123;<span class="attr">type</span>:<span class="string">&#x27;separator&#x27;</span>&#125;,</span><br><span class="line">            &#123;<span class="attr">label</span>:<span class="string">&#x27;windows&#x27;</span>,<span class="attr">type</span>:<span class="string">&#x27;submenu&#x27;</span>,<span class="attr">role</span>:<span class="string">&#x27;windowMenu&#x27;</span>&#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="attr">label</span>:<span class="string">&#x27;其他&#x27;</span>,</span><br><span class="line">        <span class="attr">submenu</span>:[</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="attr">label</span>:<span class="string">&#x27;打开&#x27;</span>, </span><br><span class="line">                <span class="attr">icon</span>:<span class="string">&#x27;./logo.ico&#x27;</span>, <span class="comment">//自定义菜单图标</span></span><br><span class="line">                <span class="attr">accelerator</span>:<span class="string">&#x27;ctrl + o&#x27;</span>, <span class="comment">//自定义菜单快捷键</span></span><br><span class="line">                <span class="title function_">click</span>(<span class="params"></span>)&#123;</span><br><span class="line">                    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;执行了自定义其他菜单&#x27;</span>)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            </span><br><span class="line">        ]</span><br><span class="line">    &#125;,</span><br><span class="line">]</span><br></pre></td></tr></table></figure>
<p>这里输出了中文字符，但vscode控制台没有设置，输出了乱码，可以进行设置：</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">chcp 65001</span><br></pre></td></tr></table></figure>
<h4 id="动态创建菜单">动态创建菜单</h4>
<p>通过Menu和MenuItem可以实现动态创建自定义菜单的功能</p>
<p>首先在主页面添加按钮和文本框：</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">&quot;addMenu&quot;</span>&gt;</span>创建自定义菜单<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">br</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">id</span>=<span class="string">&quot;menuCon&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;输入自定义菜单项内容&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">br</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">&quot;addItem&quot;</span>&gt;</span>添加菜单项<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>在js文件中创建对应的方法</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123;</span><br><span class="line">    <span class="title class_">BrowserWindow</span>,</span><br><span class="line">    getCurrentWindow,</span><br><span class="line">    <span class="title class_">Menu</span>,</span><br><span class="line">    <span class="title class_">MenuItem</span></span><br><span class="line">&#125;=<span class="built_in">require</span>(<span class="string">&#x27;@electron/remote&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="variable language_">window</span>.<span class="title function_">addEventListener</span>(<span class="string">&#x27;DOMContentLoaded&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="comment">//获取自定义菜单相关元素</span></span><br><span class="line">    <span class="keyword">let</span> addMenu=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;addMenu&#x27;</span>)</span><br><span class="line">    <span class="keyword">let</span> menuCon=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;menuCon&#x27;</span>)</span><br><span class="line">    <span class="keyword">let</span> addItem=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;addItem&#x27;</span>)</span><br><span class="line">    <span class="comment">//自定义全局菜单变量</span></span><br><span class="line">    <span class="keyword">let</span> menuItem=<span class="keyword">new</span> <span class="title class_">Menu</span>()</span><br><span class="line">    <span class="comment">//生成自定义菜单</span></span><br><span class="line">    addMenu.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        <span class="comment">//创建菜单</span></span><br><span class="line">        <span class="keyword">let</span> menuFile=<span class="keyword">new</span> <span class="title class_">MenuItem</span>(&#123;<span class="attr">label</span>:<span class="string">&#x27;文件&#x27;</span>,<span class="attr">type</span>:<span class="string">&#x27;normal&#x27;</span>&#125;)</span><br><span class="line">        <span class="keyword">let</span> menuEdit=<span class="keyword">new</span> <span class="title class_">MenuItem</span>(&#123;<span class="attr">label</span>:<span class="string">&#x27;编辑&#x27;</span>,<span class="attr">type</span>:<span class="string">&#x27;normal&#x27;</span>&#125;)</span><br><span class="line">        <span class="keyword">let</span> customMenu=<span class="keyword">new</span> <span class="title class_">MenuItem</span>(&#123;<span class="attr">label</span>:<span class="string">&#x27;自定义菜单项&#x27;</span>,<span class="attr">submenu</span>:menuItem&#125;)</span><br><span class="line">        <span class="comment">//将创建好的自定义菜单添加到menu</span></span><br><span class="line">        <span class="keyword">let</span> menu=<span class="keyword">new</span> <span class="title class_">Menu</span>()</span><br><span class="line">        menu.<span class="title function_">append</span>(menuFile)</span><br><span class="line">        menu.<span class="title function_">append</span>(menuEdit)</span><br><span class="line">        menu.<span class="title function_">append</span>(customMenu)</span><br><span class="line">        <span class="comment">//将menu放置于app中显示</span></span><br><span class="line">        <span class="title class_">Menu</span>.<span class="title function_">setApplicationMenu</span>(menu)</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="comment">//动态添加菜单项</span></span><br><span class="line">    addItem.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        <span class="comment">// 获取当前input输入框当中的内容</span></span><br><span class="line">        <span class="keyword">let</span> con = menuCon.<span class="property">value</span>.<span class="title function_">trim</span>()</span><br><span class="line">        <span class="keyword">if</span>(con)&#123;</span><br><span class="line">            menuItem.<span class="title function_">append</span>(<span class="keyword">new</span> <span class="title class_">MenuItem</span>(&#123;<span class="attr">label</span>:con,<span class="attr">type</span>:<span class="string">&#x27;normal&#x27;</span>&#125;))</span><br><span class="line">            menuCon.<span class="property">value</span>=<span class="string">&#x27;&#x27;</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// ~~~ 其他逻辑 </span></span><br><span class="line">    </span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h4 id="右键菜单">右键菜单</h4>
<p>首先定义出子菜单模板</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">let</span> rightKeyMenu=[</span><br><span class="line">    &#123;<span class="attr">label</span>:<span class="string">&#x27;Run Code&#x27;</span>&#125;,</span><br><span class="line">    &#123;<span class="attr">label</span>:<span class="string">&#x27;转到定义&#x27;</span>&#125;,</span><br><span class="line">    &#123;<span class="attr">type</span>:<span class="string">&#x27;separator&#x27;</span>&#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="attr">label</span>:<span class="string">&#x27;其他功能&#x27;</span>,</span><br><span class="line">        <span class="title function_">click</span>(<span class="params"></span>)&#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;其他功能选项被点击了&#x27;</span>)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">]</span><br><span class="line"><span class="built_in">exports</span>.<span class="property">rightKeyMenu</span>=rightKeyMenu</span><br></pre></td></tr></table></figure>
<p>在渲染进程中引入并设置：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//右键菜单</span></span><br><span class="line"><span class="keyword">const</span> &#123;rightKeyMenu&#125;=<span class="built_in">require</span>(<span class="string">&#x27;./menu/menu&#x27;</span>)</span><br><span class="line"><span class="comment">//依据右键菜单配置生成menu</span></span><br><span class="line"><span class="keyword">let</span> menu=<span class="title class_">Menu</span>.<span class="title function_">buildFromTemplate</span>(rightKeyMenu)</span><br><span class="line"></span><br><span class="line"><span class="variable language_">window</span>.<span class="title function_">addEventListener</span>(<span class="string">&#x27;DOMContentLoaded&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="comment">//获取当前窗口对象</span></span><br><span class="line">    <span class="keyword">let</span> mainWin=<span class="title function_">getCurrentWindow</span>()</span><br><span class="line">    <span class="comment">//给鼠标右击添加监听</span></span><br><span class="line">    <span class="variable language_">window</span>.<span class="title function_">addEventListener</span>(<span class="string">&#x27;contextmenu&#x27;</span>,<span class="function">(<span class="params">ev</span>)=&gt;</span>&#123;</span><br><span class="line">        ev.<span class="title function_">preventDefault</span>()</span><br><span class="line">        <span class="comment">//弹出菜单</span></span><br><span class="line">        menu.<span class="title function_">popup</span>(&#123;<span class="attr">window</span>:mainWin&#125;,<span class="literal">false</span>)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h3 id="关于更多">关于更多</h3>
<h4 id="主进程与渲染进程通信">主进程与渲染进程通信</h4>
<p>即类似发布订阅模式的通信，分为同步和异步两种：</p>
<p>渲染进程-页面：</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">&quot;commAsync&quot;</span>&gt;</span>渲到主异步操作<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">br</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">&quot;commSync&quot;</span>&gt;</span>渲到主同步操作<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>渲染进程-js：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123;ipcRenderer&#125; = <span class="built_in">require</span>(<span class="string">&#x27;electron&#x27;</span>)</span><br><span class="line"><span class="variable language_">window</span>.<span class="property">onload</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="comment">//获取元素</span></span><br><span class="line">    <span class="keyword">let</span> asyncBtn=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;commAsync&#x27;</span>)</span><br><span class="line">    <span class="keyword">let</span> syncBtn=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;commSync&#x27;</span>)</span><br><span class="line">    <span class="comment">//01 采用异步api在渲染进程中给主进程发送消息</span></span><br><span class="line">    asyncBtn.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        ipcRenderer.<span class="title function_">send</span>(<span class="string">&#x27;msg1&#x27;</span>,<span class="string">&#x27;当前是来自渲染进程的异步消息&#x27;</span>)</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="comment">//02 采用同步的方式完成数据通信</span></span><br><span class="line">    syncBtn.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        <span class="keyword">let</span> val= ipcRenderer.<span class="title function_">sendSync</span>(<span class="string">&#x27;msg2&#x27;</span>,<span class="string">&#x27;当前是来自渲染进程的同步消息&#x27;</span>)</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(val)</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="comment">//接收消息</span></span><br><span class="line">    ipcRenderer.<span class="title function_">on</span>(<span class="string">&#x27;msg1Re&#x27;</span>,<span class="function">(<span class="params">ev,data</span>)=&gt;</span>&#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(data)</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="comment">//接收主进程的主动消息</span></span><br><span class="line">    ipcRenderer.<span class="title function_">on</span>(<span class="string">&#x27;mtp&#x27;</span>,<span class="function">(<span class="params">ev,data</span>)=&gt;</span>&#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(data)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>主进程：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123;app,<span class="title class_">BrowserWindow</span>,ipcMain&#125;=<span class="built_in">require</span>(<span class="string">&#x27;electron&#x27;</span>)</span><br><span class="line"><span class="comment">//主进程接收消息操作</span></span><br><span class="line">ipcMain.<span class="title function_">on</span>(<span class="string">&#x27;msg1&#x27;</span>,<span class="function">(<span class="params">ev,data</span>)=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(data)</span><br><span class="line">    <span class="comment">//收到消息后回复，这里ev.sender相当于ipcMain</span></span><br><span class="line">    ev.<span class="property">sender</span>.<span class="title function_">send</span>(<span class="string">&#x27;msg1Re&#x27;</span>,<span class="string">&#x27;这是来自主进程的异步回复消息&#x27;</span>)</span><br><span class="line">&#125;)</span><br><span class="line">ipcMain.<span class="title function_">on</span>(<span class="string">&#x27;msg2&#x27;</span>,<span class="function">(<span class="params">ev,data</span>)=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(data)</span><br><span class="line">    <span class="comment">//收到消息后同步回复，这里ev.sender相当于ipcMain</span></span><br><span class="line">    ev.<span class="property">returnValue</span>=<span class="string">&#x27;这是来自主进程的同步回复消息&#x27;</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>可以分别在终端(控制台)和应用的控制台(渲染进程)看到打印的消息。</p>
<h4 id="渲染进程间通信">渲染进程间通信</h4>
<p>渲染进程之间无法直接进行通信，需要借助一个媒介。</p>
<p><strong>借用localStorage作为媒介：</strong></p>
<p>创建subWin1.html作为子窗口，经由index.js发送通信让主进程创建：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//index.js发送消息让主进程打开子窗口，并将信息存入localStorage</span></span><br><span class="line"><span class="variable language_">window</span>.<span class="property">onload</span> = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="comment">//获取元素</span></span><br><span class="line">    <span class="keyword">let</span> oBtn=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;subBtn&#x27;</span>)</span><br><span class="line">    oBtn.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        ipcRenderer.<span class="title function_">send</span>(<span class="string">&#x27;openWin2&#x27;</span>,<span class="string">&#x27;来自index的数据&#x27;</span>)</span><br><span class="line">        <span class="comment">//打开窗口后保存数据至localStorage</span></span><br><span class="line">        <span class="variable language_">localStorage</span>.<span class="title function_">setItem</span>(<span class="string">&#x27;name&#x27;</span>,<span class="string">&#x27;我是localStorage里的值&#x27;</span>)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//main.js接收index.js渲染进程发送的数据，然后完成后续的逻辑</span></span><br><span class="line">ipcMain.<span class="title function_">on</span>(<span class="string">&#x27;openWin2&#x27;</span>,<span class="function">(<span class="params">ev,data</span>)=&gt;</span>&#123;</span><br><span class="line">    <span class="comment">//接收到渲染进程的点击信息后完成窗口list的打开</span></span><br><span class="line">    <span class="keyword">let</span> subWin1=<span class="keyword">new</span> <span class="title class_">BrowserWindow</span>(&#123;</span><br><span class="line">        <span class="attr">width</span>:<span class="number">400</span>,</span><br><span class="line">        <span class="attr">height</span>:<span class="number">300</span>,</span><br><span class="line">        <span class="attr">parent</span>:<span class="title class_">BrowserWindow</span>.<span class="title function_">fromId</span>(mainWinId),</span><br><span class="line">        <span class="attr">webPreferences</span>:&#123;</span><br><span class="line">            <span class="attr">nodeIntegration</span>:<span class="literal">true</span>,</span><br><span class="line">            <span class="attr">contextIsolation</span>:<span class="literal">false</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">    subWin1.<span class="title function_">loadFile</span>(<span class="string">&#x27;subWin1.html&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">    subWin1.<span class="title function_">on</span>(<span class="string">&#x27;close&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        subWin1=<span class="literal">null</span></span><br><span class="line">    &#125;)</span><br><span class="line">	</span><br><span class="line">    <span class="comment">//将接收到的index.js的通信转发给subWin1</span></span><br><span class="line">    subWin1.<span class="property">webContents</span>.<span class="title function_">on</span>(<span class="string">&#x27;did-finish-load&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        subWin1.<span class="property">webContents</span>.<span class="title function_">send</span>(<span class="string">&#x27;its&#x27;</span>,data)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>这时subWin1.js可通过localStorage接收</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123;ipcRenderer&#125; = <span class="built_in">require</span>(<span class="string">&#x27;electron&#x27;</span>)</span><br><span class="line"><span class="variable language_">window</span>.<span class="property">onload</span>=<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">let</span> txt=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;txt&#x27;</span>)</span><br><span class="line">    <span class="keyword">let</span> val=<span class="variable language_">localStorage</span>.<span class="title function_">getItem</span>(<span class="string">&#x27;name&#x27;</span>)</span><br><span class="line">    txt.<span class="property">value</span>=val</span><br><span class="line"></span><br><span class="line">    <span class="comment">//在sub中发送数据给主进程main.js</span></span><br><span class="line">    <span class="keyword">let</span> btn=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;btn&#x27;</span>)</span><br><span class="line">    btn.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        ipcRenderer.<span class="title function_">send</span>(<span class="string">&#x27;stm&#x27;</span>,<span class="string">&#x27;来自sub进程&#x27;</span>)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>借用主进程作为媒介</strong></p>
<p>在上面的代码中已经有相关的记录：</p>
<p>第一块 index.js发送到主进程main.js中的创建窗口信息中携带了其他信息： <code>ipcRenderer.send('openWin2','来自index的数据')</code> 这时，main.js接收到后，在创建完成窗口的事件 <code>did-finish-load</code> 后将信息转发给了subWin，subWin可以通过 <code>ipcRenderer</code> 进行接收。</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">ipcRenderer.<span class="title function_">on</span>(<span class="string">&#x27;its&#x27;</span>,<span class="function">(<span class="params">ev,data</span>)=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">let</span> txt=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;txt2&#x27;</span>)</span><br><span class="line">    txt.<span class="property">value</span>=data</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h4 id="Dialog模块">Dialog模块</h4>
<p>详情见官方文档 <a target="_blank" rel="noopener" href="https://www.electronjs.org/zh/docs/latest/api/dialog">dialog | Electron (electronjs.org)</a></p>
<p>dialog共有 <code>open</code> <code>save</code> <code>error</code> <code>message</code> <code>certificateTrust</code> 几种，用法大差不差，最好的方式还是读文档。下面是一些示例：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//对话框</span></span><br><span class="line"><span class="keyword">let</span> dBtn=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;openDialog&#x27;</span>)</span><br><span class="line">dBtn.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="keyword">async</span> ()=&gt;&#123;</span><br><span class="line">    <span class="keyword">const</span> result= <span class="keyword">await</span> dialog.<span class="title function_">showOpenDialog</span>(&#123;</span><br><span class="line">        <span class="attr">defaultPath</span>:__dirname,<span class="comment">//默认路径指向当前目录</span></span><br><span class="line">        <span class="attr">buttonLabel</span>:<span class="string">&#x27;请选择~&#x27;</span>,<span class="comment">//确认按钮</span></span><br><span class="line">        <span class="attr">title</span>:<span class="string">&#x27;【测试】请选择哦~&#x27;</span>,</span><br><span class="line">        <span class="attr">properties</span>:[<span class="string">&#x27;openFile&#x27;</span>,<span class="string">&#x27;multiSelections&#x27;</span>],<span class="comment">//打开文件</span></span><br><span class="line">        <span class="comment">//properties:[&#x27;openDirectory&#x27;,&#x27;multiSelections&#x27;],//打开文件夹</span></span><br><span class="line">        <span class="attr">filters</span>:[</span><br><span class="line">            &#123;<span class="string">&quot;name&quot;</span>:<span class="string">&#x27;代码文件&#x27;</span>,<span class="attr">extensions</span>:[<span class="string">&#x27;js&#x27;</span>,<span class="string">&#x27;json&#x27;</span>,<span class="string">&#x27;html&#x27;</span>]&#125;,</span><br><span class="line">            &#123;<span class="string">&quot;name&quot;</span>:<span class="string">&#x27;图片文件&#x27;</span>,<span class="attr">extensions</span>:[<span class="string">&#x27;jpg&#x27;</span>,<span class="string">&#x27;png&#x27;</span>,<span class="string">&#x27;gif&#x27;</span>]&#125;,</span><br><span class="line">        ],</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(result)</span><br><span class="line">    <span class="keyword">if</span>(result.<span class="property">canceled</span>)&#123;</span><br><span class="line">        <span class="comment">//显示错误对话框</span></span><br><span class="line">        dialog.<span class="title function_">showErrorBox</span>(<span class="string">&#x27;没有选择任何文件&#x27;</span>,<span class="string">&#x27;您没有选择任何文件额~&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>值得一提的是，electron的confirm选择对话框是放在MessageBox中的：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//监听窗口关闭操作</span></span><br><span class="line"><span class="variable language_">window</span>.<span class="property">onbeforeunload</span>=<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">const</span> choice= dialog.<span class="title function_">showMessageBoxSync</span>(<span class="title function_">getCurrentWindow</span>(),&#123;</span><br><span class="line">        <span class="attr">message</span>:<span class="string">&#x27;未保存信息将会清除，确定要退出吗？&#x27;</span>,</span><br><span class="line">        <span class="attr">type</span>:<span class="string">&#x27;warning&#x27;</span>,</span><br><span class="line">        <span class="attr">buttons</span>:[<span class="string">&#x27;确定退出&#x27;</span>,<span class="string">&#x27;取消~&#x27;</span>],</span><br><span class="line">        <span class="attr">defaultId</span>:<span class="number">1</span>,</span><br><span class="line">        <span class="attr">title</span>:<span class="string">&#x27;退出程序确认&#x27;</span>,</span><br><span class="line">        <span class="attr">detail</span>:<span class="string">&#x27;确认退出，数据将清空&#x27;</span>,</span><br><span class="line">        <span class="attr">cancelId</span>:<span class="number">1</span>,</span><br><span class="line"></span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="keyword">if</span>(choice==<span class="number">0</span>)&#123;</span><br><span class="line">        mainWin.<span class="title function_">destroy</span>()</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="Shell模块">Shell模块</h4>
<p>shell能够在浏览器打开指定网页、在文件资源管理器打开某个路径。</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123;shell&#125; = <span class="built_in">require</span>(<span class="string">&#x27;electron&#x27;</span>)</span><br><span class="line"><span class="variable language_">window</span>.<span class="property">onload</span>=<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="comment">//打开url</span></span><br><span class="line">    <span class="keyword">let</span> openFolder=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;openFolder&#x27;</span>)</span><br><span class="line">    openFolder.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">(<span class="params">ev</span>)=&gt;</span>&#123;</span><br><span class="line">        <span class="keyword">let</span> urlPath=<span class="string">&#x27;http://www.baidu.com&#x27;</span></span><br><span class="line">        <span class="comment">//会唤醒浏览器并打开指定url</span></span><br><span class="line">        shell.<span class="title function_">openExternal</span>(urlPath) </span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> path=<span class="built_in">require</span>(<span class="string">&#x27;path&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> &#123;shell&#125; = <span class="built_in">require</span>(<span class="string">&#x27;electron&#x27;</span>)</span><br><span class="line"><span class="variable language_">window</span>.<span class="property">onload</span>=<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="comment">//打开url</span></span><br><span class="line">    <span class="keyword">let</span> openFolder=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;openFolder&#x27;</span>)</span><br><span class="line">    openFolder.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">(<span class="params">ev</span>)=&gt;</span>&#123;</span><br><span class="line">        <span class="comment">//打开 文件资源管理器</span></span><br><span class="line">        shell.<span class="title function_">showItemInFolder</span>(path.<span class="title function_">resolve</span>(__filename)) <span class="comment">//打开当前文件</span></span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>通过iframe能够达到在窗口显示某个网页的效果：</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">iframe</span> <span class="attr">src</span>=<span class="string">&quot;http://www.baidu.com&quot;</span> <span class="attr">frameborder</span>=<span class="string">&quot;0&quot;</span> <span class="attr">id</span>=<span class="string">&quot;webview&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">iframe</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">style</span>&gt;</span><span class="language-css"></span></span><br><span class="line"><span class="language-css">    *&#123;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">margin</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">padding</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">    &#125;</span></span><br><span class="line"><span class="language-css">    <span class="selector-tag">iframe</span>&#123;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">top</span>:<span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">left</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">width</span>: <span class="number">100%</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">height</span>: <span class="number">100%</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">position</span>: fixed;</span></span><br><span class="line"><span class="language-css">    &#125;</span></span><br><span class="line"><span class="language-css"></span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//自定义菜单</span></span><br><span class="line"><span class="keyword">const</span> &#123;<span class="title class_">BrowserWindow</span>,shell&#125; =<span class="built_in">require</span>(<span class="string">&#x27;electron&#x27;</span>)</span><br><span class="line"><span class="keyword">let</span> shellMenu=[</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="attr">label</span>:<span class="string">&quot;菜单&quot;</span>,</span><br><span class="line">        <span class="attr">submenu</span>:[</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="attr">label</span>:<span class="string">&#x27;关于&#x27;</span>,</span><br><span class="line">                <span class="title function_">click</span>(<span class="params"></span>)&#123;</span><br><span class="line">                    shell.<span class="title function_">openExternal</span>(<span class="string">&#x27;https://kaiwu.lagou.com/&#x27;</span>)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="attr">label</span>:<span class="string">&#x27;打开&#x27;</span>,</span><br><span class="line">                <span class="title function_">click</span>(<span class="params"></span>)&#123;</span><br><span class="line">                    <span class="comment">//通过主进程发送消息</span></span><br><span class="line">                    <span class="title class_">BrowserWindow</span>.<span class="title function_">getFocusedWindow</span>().<span class="property">webContents</span>.<span class="title function_">send</span>(<span class="string">&#x27;openUrl&#x27;</span>)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">]</span><br><span class="line"><span class="built_in">exports</span>.<span class="property">shellMenu</span>=shellMenu</span><br><span class="line"></span><br><span class="line"><span class="comment">//在main.js中生成菜单</span></span><br><span class="line"><span class="comment">//实现略,上面menu提过了</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//在shell.js接收主进程发送的消息，更换iframe的url</span></span><br><span class="line">ipcRenderer.<span class="title function_">on</span>(<span class="string">&#x27;openUrl&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">let</span> iframe=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;webview&#x27;</span>)</span><br><span class="line">    iframe.<span class="property">src</span>=<span class="string">&#x27;https://www.lagou.com&#x27;</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h4 id="消息通知">消息通知</h4>
<p>即右下角弹窗通知，使用window原生：</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">&quot;notice&quot;</span>&gt;</span>打开消息通知<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="variable language_">window</span>.<span class="property">onload</span>=<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="comment">//打开消息通知</span></span><br><span class="line">    <span class="keyword">let</span> notice=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;notice&#x27;</span>)</span><br><span class="line">    notice.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        <span class="keyword">let</span> option=&#123;</span><br><span class="line">            <span class="attr">title</span>:<span class="string">&#x27;测试通知&#x27;</span>,</span><br><span class="line">            <span class="attr">body</span>:<span class="string">&#x27;hi~你现在被通知了~&#x27;</span>,</span><br><span class="line">            <span class="attr">icon</span>:<span class="string">&#x27;./logo.ico&#x27;</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">let</span> myNotice=<span class="keyword">new</span> <span class="variable language_">window</span>.<span class="title class_">Notification</span>(option.<span class="property">title</span>,option)</span><br><span class="line">        myNotice.<span class="property">onclick</span>=<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;点击后的动作&#x27;</span>)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="全局快捷键">全局快捷键</h4>
<p>注册全局快捷键：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//注册全局快捷键 ready可以监听多次</span></span><br><span class="line">app.<span class="title function_">on</span>(<span class="string">&#x27;ready&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">let</span> ret= globalShortcut.<span class="title function_">register</span>(<span class="string">&#x27;ctrl + q&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;快捷键注册成功&#x27;</span>)</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="keyword">if</span>(!ret)&#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;注册失败&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//判断是否已注册</span></span><br><span class="line">    <span class="keyword">if</span>(globalShortcut.<span class="title function_">isRegistered</span>(<span class="string">&#x27;ctrl + q&#x27;</span>))&#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;ctrl + q 已注册&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>在程序退出前注销快捷键：</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="comment">//退出前注销快捷键</span></span><br><span class="line">app.<span class="title function_">on</span>(<span class="string">&#x27;will-quit&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    globalShortcut.<span class="title function_">unregister</span>(<span class="string">&#x27;ctrl+q&#x27;</span>)</span><br><span class="line">    globalShortcut.<span class="title function_">unregisterAll</span>()</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h4 id="剪贴板操作">剪贴板操作</h4>
<p>将内容复制到剪切板clipboard，并在其他地方读取出来。</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">input</span> <span class="attr">id</span>=<span class="string">&quot;copyBox&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;复制内容&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">input</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">&quot;copyBtn&quot;</span>&gt;</span>复制<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">br</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">input</span> <span class="attr">id</span>=<span class="string">&quot;pasteBox&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;粘贴内容&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">input</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">&quot;pasteBtn&quot;</span>&gt;</span>粘贴<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">br</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">&quot;pic&quot;</span>&gt;</span>将图片拷贝至剪切板再粘贴至界面<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="variable language_">window</span>.<span class="property">onload</span>=<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="comment">//剪贴板</span></span><br><span class="line">    <span class="keyword">let</span> copyBox= <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;copyBox&#x27;</span>)</span><br><span class="line">    <span class="keyword">let</span> copyBtn=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;copyBtn&#x27;</span>)</span><br><span class="line">    <span class="keyword">let</span> pasteBox=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;pasteBox&#x27;</span>)</span><br><span class="line">    <span class="keyword">let</span> pasteBtn=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;pasteBtn&#x27;</span>)</span><br><span class="line">    <span class="keyword">let</span> pic=<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;pic&#x27;</span>)</span><br><span class="line">    <span class="comment">//复制按钮</span></span><br><span class="line">    copyBtn.<span class="property">onclick</span>=<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        clipboard.<span class="title function_">writeText</span>(copyBox.<span class="property">value</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//粘贴</span></span><br><span class="line">    pasteBtn.<span class="property">onclick</span>=<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        pasteBox.<span class="property">value</span>= clipboard.<span class="title function_">readText</span>()</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    pic.<span class="property">onclick</span>=<span class="function">()=&gt;</span>&#123;</span><br><span class="line">        <span class="comment">//将图片放置于剪切板中要求图片类型属于nativeImage实例</span></span><br><span class="line">        <span class="keyword">let</span> oImage=nativeImage.<span class="title function_">createFromPath</span>(<span class="string">&#x27;./logo.png&#x27;</span>)</span><br><span class="line">        <span class="comment">//复制</span></span><br><span class="line">        clipboard.<span class="title function_">writeImage</span>(oImage)</span><br><span class="line"></span><br><span class="line">        <span class="comment">//将剪切板中的图片作为dom粘贴到界面上</span></span><br><span class="line">        <span class="keyword">let</span> pasteImage=clipboard.<span class="title function_">readImage</span>()</span><br><span class="line">        <span class="keyword">let</span> oImgDom=<span class="keyword">new</span> <span class="title class_">Image</span>()</span><br><span class="line">        oImgDom.<span class="property">src</span>=pasteImage.<span class="title function_">toDataURL</span>()</span><br><span class="line">        <span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">appendChild</span>(oImgDom)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<div class="note warning simple"><p>这里只是简单记录一下在尝试electron时的一些操作和特性，实际使用还是依赖官方文档为准。</p>
</div>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="https://lienle.gitee.io">Lenl</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://lienle.gitee.io/notes/electronLearn/">https://lienle.gitee.io/notes/electronLearn/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://lienle.gitee.io" target="_blank">LenlBlog</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/Vue/">Vue</a><a class="post-meta__tags" href="/tags/Electron/">Electron</a><a class="post-meta__tags" href="/tags/Node-Js/">Node.Js</a></div><div class="post_share"><div class="social-share" data-image="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="/img/wechat.png" target="_blank"><img class="post-qr-code-img" src= "/img/hexo_loading.gif" data-lazy-src="/img/wechat.png" alt="微信"/></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="/img/alipay.png" target="_blank"><img class="post-qr-code-img" src= "/img/hexo_loading.gif" data-lazy-src="/img/alipay.png" alt="支付宝"/></a><div class="post-qr-code-desc">支付宝</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/notes/GitLearn/" title="Git基本使用与协作开发学习"><img class="cover" src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">Git基本使用与协作开发学习</div></div></a></div><div class="next-post pull-right"><a href="/bugs/bugsOne/" title="记录BUG与坑--Java相关"><img class="cover" src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">记录BUG与坑--Java相关</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/notes/electronVue/" title="Electron+Vue项目搭建"><img class="cover" src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-05-14</div><div class="title">Electron+Vue项目搭建</div></div></a></div><div><a href="/notes/PdfView/" title="基于pdf.js的前后端分离式PDF文件预览实现"><img class="cover" src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-08-06</div><div class="title">基于pdf.js的前后端分离式PDF文件预览实现</div></div></a></div><div><a href="/notes/chunkFile/" title="基于SpringBoot与Vue的大文件分片上传与流式下载"><img class="cover" src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-05-13</div><div class="title">基于SpringBoot与Vue的大文件分片上传与流式下载</div></div></a></div></div></div><hr/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div class="vcomment" id="vcomment"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src= "/img/hexo_loading.gif" data-lazy-src="/img/lenl.png" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">Lenl</div><div class="author-info__description">心有所向，日复一日，必有精进~</div></div><div class="card-info-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">17</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">25</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">8</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/vimianma"><i class="fab fa-github"></i><span>View me</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://gitee.com/lienle" target="_blank" title="Gitee"><i class="fa-brands fa-git" style="color: #c71d23;"></i></a><a class="social-icon" href="https://github.com/vimianma" target="_blank" title="Github"><i class="fab fa-github" style="color: #24292e;"></i></a><a class="social-icon" href="mailto:lenl412@163.com" target="_blank" title="Email"><i class="fas fa-envelope" style="color: #4a7dbe;"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">本站意在记录个人生活中的所学所感所想所获；<br/>心有所向，日复一日，必有精进~~~<br>请多多指教~</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#Electron%E5%9F%BA%E6%9C%AC"><span class="toc-number">1.</span> <span class="toc-text">Electron基本</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%8A%80%E6%9C%AF%E6%9E%B6%E6%9E%84"><span class="toc-number">1.1.</span> <span class="toc-text">技术架构</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Electron%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B"><span class="toc-number">1.2.</span> <span class="toc-text">Electron工作流程</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%B8%BB%E8%BF%9B%E7%A8%8B"><span class="toc-number">1.2.1.</span> <span class="toc-text">主进程</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%B8%B2%E6%9F%93%E8%BF%9B%E7%A8%8B"><span class="toc-number">1.2.2.</span> <span class="toc-text">渲染进程</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Electron%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA"><span class="toc-number">1.3.</span> <span class="toc-text">Electron环境搭建</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Electron%E5%AD%A6%E4%B9%A0"><span class="toc-number">2.</span> <span class="toc-text">Electron学习</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Electron%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E4%BA%8B%E4%BB%B6"><span class="toc-number">2.1.</span> <span class="toc-text">Electron生命周期事件</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B3%E4%BA%8E%E7%AA%97%E5%8F%A3"><span class="toc-number">2.2.</span> <span class="toc-text">关于窗口</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%AA%97%E5%8F%A3%E5%B0%BA%E5%AF%B8"><span class="toc-number">2.2.1.</span> <span class="toc-text">窗口尺寸</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%AA%97%E5%8F%A3%E6%A0%87%E9%A2%98%E5%8F%8A%E7%8E%AF%E5%A2%83"><span class="toc-number">2.2.2.</span> <span class="toc-text">窗口标题及环境</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%AA%97%E5%8F%A3"><span class="toc-number">2.2.3.</span> <span class="toc-text">自定义窗口</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%98%BB%E6%AD%A2%E7%AA%97%E5%8F%A3%E5%85%B3%E9%97%AD"><span class="toc-number">2.2.4.</span> <span class="toc-text">阻止窗口关闭</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%88%B6%E5%AD%90%E5%8F%8A%E6%A8%A1%E6%80%81%E7%AA%97%E5%8F%A3"><span class="toc-number">2.2.5.</span> <span class="toc-text">父子及模态窗口</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%85%B3%E4%BA%8E%E6%96%87%E6%A1%A3"><span class="toc-number">2.2.6.</span> <span class="toc-text">关于文档</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B3%E4%BA%8E%E8%8F%9C%E5%8D%95"><span class="toc-number">2.3.</span> <span class="toc-text">关于菜单</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%8F%9C%E5%8D%95"><span class="toc-number">2.3.1.</span> <span class="toc-text">自定义菜单</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%8F%9C%E5%8D%95%E8%A7%92%E8%89%B2%E5%8F%8A%E7%B1%BB%E5%9E%8B"><span class="toc-number">2.3.2.</span> <span class="toc-text">菜单角色及类型</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8A%A8%E6%80%81%E5%88%9B%E5%BB%BA%E8%8F%9C%E5%8D%95"><span class="toc-number">2.3.3.</span> <span class="toc-text">动态创建菜单</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8F%B3%E9%94%AE%E8%8F%9C%E5%8D%95"><span class="toc-number">2.3.4.</span> <span class="toc-text">右键菜单</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B3%E4%BA%8E%E6%9B%B4%E5%A4%9A"><span class="toc-number">2.4.</span> <span class="toc-text">关于更多</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%B8%BB%E8%BF%9B%E7%A8%8B%E4%B8%8E%E6%B8%B2%E6%9F%93%E8%BF%9B%E7%A8%8B%E9%80%9A%E4%BF%A1"><span class="toc-number">2.4.1.</span> <span class="toc-text">主进程与渲染进程通信</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%B8%B2%E6%9F%93%E8%BF%9B%E7%A8%8B%E9%97%B4%E9%80%9A%E4%BF%A1"><span class="toc-number">2.4.2.</span> <span class="toc-text">渲染进程间通信</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Dialog%E6%A8%A1%E5%9D%97"><span class="toc-number">2.4.3.</span> <span class="toc-text">Dialog模块</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Shell%E6%A8%A1%E5%9D%97"><span class="toc-number">2.4.4.</span> <span class="toc-text">Shell模块</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%B6%88%E6%81%AF%E9%80%9A%E7%9F%A5"><span class="toc-number">2.4.5.</span> <span class="toc-text">消息通知</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%85%A8%E5%B1%80%E5%BF%AB%E6%8D%B7%E9%94%AE"><span class="toc-number">2.4.6.</span> <span class="toc-text">全局快捷键</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%89%AA%E8%B4%B4%E6%9D%BF%E6%93%8D%E4%BD%9C"><span class="toc-number">2.4.7.</span> <span class="toc-text">剪贴板操作</span></a></li></ol></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/notes/dockerNotes/" title="Docker备忘笔记"><img src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Docker备忘笔记"/></a><div class="content"><a class="title" href="/notes/dockerNotes/" title="Docker备忘笔记">Docker备忘笔记</a><time datetime="2024-04-06T13:17:09.000Z" title="发表于 2024-04-06 21:17:09">2024-04-06</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/notes/mysqlInstall/" title="mysql压缩包方式本地安装"><img src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="mysql压缩包方式本地安装"/></a><div class="content"><a class="title" href="/notes/mysqlInstall/" title="mysql压缩包方式本地安装">mysql压缩包方式本地安装</a><time datetime="2024-01-03T05:33:33.000Z" title="发表于 2024-01-03 13:33:33">2024-01-03</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/notes/PdfView/" title="基于pdf.js的前后端分离式PDF文件预览实现"><img src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="基于pdf.js的前后端分离式PDF文件预览实现"/></a><div class="content"><a class="title" href="/notes/PdfView/" title="基于pdf.js的前后端分离式PDF文件预览实现">基于pdf.js的前后端分离式PDF文件预览实现</a><time datetime="2023-08-06T02:18:26.000Z" title="发表于 2023-08-06 10:18:26">2023-08-06</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/notes/electronVue/" title="Electron+Vue项目搭建"><img src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Electron+Vue项目搭建"/></a><div class="content"><a class="title" href="/notes/electronVue/" title="Electron+Vue项目搭建">Electron+Vue项目搭建</a><time datetime="2023-05-14T02:36:59.000Z" title="发表于 2023-05-14 10:36:59">2023-05-14</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/notes/chunkFile/" title="基于SpringBoot与Vue的大文件分片上传与流式下载"><img src= "/img/hexo_loading.gif" data-lazy-src="https://z4a.net/images/2023/04/22/fcc1d07f3136fe8e818242a6534391c8.md.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="基于SpringBoot与Vue的大文件分片上传与流式下载"/></a><div class="content"><a class="title" href="/notes/chunkFile/" title="基于SpringBoot与Vue的大文件分片上传与流式下载">基于SpringBoot与Vue的大文件分片上传与流式下载</a><time datetime="2023-05-13T13:57:28.000Z" title="发表于 2023-05-13 21:57:28">2023-05-13</time></div></div></div></div></div></div></main><footer id="footer" style="background: -#484847"><div id="footer-wrap"><div class="copyright">&copy;2023 - 2024 By Lenl</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text">Hi, welcome to my blog !</div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.umd.min.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><div class="js-pjax"><script>function loadValine () {
  function initValine () {
    const valine = new Valine(Object.assign({
      el: '#vcomment',
      appId: 'dBlOeCLNhBxbSdZO44fRKdBa-gzGzoHsz',
      appKey: 'DCSQoDhPl0UOF7Ix9Imdfd9X',
      avatar: 'monsterid',
      serverURLs: '',
      emojiMaps: "",
      path: window.location.pathname,
      visitor: false
    }, null))
  }

  if (typeof Valine === 'function') initValine() 
  else getScript('https://cdn.jsdelivr.net/npm/valine/dist/Valine.min.js').then(initValine)
}

if ('Valine' === 'Valine' || !false) {
  if (false) btf.loadComment(document.getElementById('vcomment'),loadValine)
  else setTimeout(loadValine, 0)
} else {
  function loadOtherComment () {
    loadValine()
  }
}</script></div><script defer="defer" id="ribbon" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-ribbon.min.js" size="150" alpha="0.6" zIndex="-1" mobile="false" data-click="true"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div class="no-result" id="local-search-results"></div><div id="local-search-stats-wrap"></div></div></div><div id="search-mask"></div><script src="/js/search/local-search.js"></script></div></div></body></html>